from ganges.text import TextBlock


TAB = "   "

class Container(object):
    __slots__ = ["__dict__", "__weakref__", "__reclock__"]
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
        self.__reclock__ = False
    def __repr__(self):
        if self.__reclock__:
            return "<...>"
        try:
            self.__reclock__ = True
            attrs = sorted("%s = %r" % (k, v) for k, v in self)
            return "%s(%s)" % (self.__class__.__name__, ", ".join(attrs))
        finally:
            self.__reclock__ = False
    def __str__(self):
        return self.__pretty__()
    def __iter__(self):
        return self.__dict__.iteritems()
    def __pretty__(self, tab = None):
        if self.__reclock__:
            return "<...>"
        if tab is None:
            tab = TAB
        self.__reclock__ = True
        try:
            blk = TextBlock("%s:" % (self.__class__.__name__,))
            attrs = []
            for k, v in self:
                if k.startswith("_"):
                    continue
                if hasattr(v, "__pretty__"):
                    attrs.append("%s = %s" % (k, v.__pretty__(tab)))
                else:
                    attrs.append("%s = %r" % (k, v))
            attrs.sort()
            blk.create_child(*attrs)
            return blk.render(tab = tab)
        finally:
            self.__reclock__ = False
    def __delitem__(self, key):
        del self.__dict__[key]
    def __getitem__(self, key):
        return self.__dict__[key]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __contains__(self, key):
        return key in self.__dict__
    def __nonzero__(self):
        return bool(self.__dict__)
    def __eq__(self, other):
        try:
            if isinstance(other, dict):
                return self.__dict__ == other
            else:
                return self.__dict__ == other.__dict__
        except AttributeError:
            return False
    def __ne__(self, other):
        return not (self == other)


class ListContainer(list):
    __reclock__ = False
    def __str__(self):
        return self.__pretty__()
    def __pretty__(self, tab = None):
        if self.__reclock__:
            return "<...>"
        if tab is None:
            tab = TAB
        self.__reclock__ = True
        try:
            if not self:
                return "[]"
            blk = TextBlock("[")
            items = []
            for item in self:
                if hasattr(item, "__pretty__"):
                    items.append(item.__pretty__())
                else:
                    items.append(repr(item))
            blk.create_child(*items)
            blk.append("]")
            return blk.render(tab = tab)
        finally:
            self.__reclock__ = False


if __name__ == "__main__":
    c = Container(
        a = 5, 
        b = "moshe", 
        c = Container(
            d = 17, 
            e = 2.3
        ),
        g = Container(
            h = 9, 
            i = Container(
                j = Container(
                    k = Container(
                        l = 88,
                        m = 99
                    )
                )
            ),
        ),
        n = ListContainer([
            19, 
            20, 
            ListContainer([24, 25]), 
            21, 
            Container(
                o = 22, 
                p = 23, 
                q = ListContainer()
            ),
            26, 
        ])
    )
    c.c["f"] = c
    print c



